package com.fingard.dsp.bank.directbank.weixin01;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.bankInterface.ITransaction;
import com.fingard.dsp.bank.reqrespobj.transaction.Req7515TodayTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.Req7516HisTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.RetAtsTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.detail.RetAtsTransDetail;
import com.fingard.text.SplitHelper;
import com.fingard.text.StringHelper;
import com.fingard.xml.XmlTextReader;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.StringReader;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;

@Component("WEIXIN01Transaction")
public class WEIXIN01Transaction extends WEIXIN01Base implements ITransaction {
    public RetAtsTrans d_7516_HisTrans(Req7516HisTrans p_req7516) throws Exception {
        if (getBankConfig().getValueAsBool("downloadfundflow")) {
            return d_7516_FundHisTrans(p_req7516);
        } else {
            return d_7516_WXHisTrans(p_req7516);
        }
    }

    public RetAtsTrans d_7516_WXHisTrans(Req7516HisTrans p_req7516) throws Exception {
        RetAtsTrans retAts = new RetAtsTrans(reqHeader);
        retAts.writeStart();

        String tmpRespCode;
        String tmpRespInfo = "";

        Date dateFrom = p_req7516.getDateFrom();
        Date dateTo = p_req7516.getDateTo();


        int successCnt = 0;
        StringBuilder failMsg = new StringBuilder();
        while (dateFrom.compareTo(dateTo) <= 0) {
            ActSetItem actItem = this.getBankConfig().getActSetItemByAny(p_req7516.actNum, "", "", "unifiedorder");
            if (actItem != null) {
                StringBuilder sbXml = new StringBuilder();
                ArrayList<String> arrayParams = new ArrayList<String>();

                sbXml.append("<xml>\r\n");
                String appid = actItem.appId;
                sbXml.append("  <appid>" + appid + "</appid>\r\n");
                arrayParams.add("appid=" + appid);

                String mch_id = actItem.merchantId;
                sbXml.append("  <mch_id>" + mch_id + "</mch_id>\r\n");
                arrayParams.add("mch_id=" + mch_id);

                //ATSES-23454 微信对账单下载，银行返回 No Bill Exist，服务商模式下需要使用服务商的商户id
                if (getBankConfig().getValueAsBool("isThirdPartyServiceProviderMode")) {

                    String subAppid = actItem.subAppId;
                    sbXml.append("  <sub_appid>" + subAppid + "</sub_appid>\r\n");
                    arrayParams.add("sub_appid=" + subAppid);

                    String subMerchantId = actItem.subMerchantId;
                    sbXml.append("  <sub_mch_id>" + subMerchantId + "</sub_mch_id>\r\n");
                    arrayParams.add("sub_mch_id=" + subMerchantId);
                }

                String nonce_str = get_nonce_str();
                sbXml.append("  <nonce_str>" + nonce_str + "</nonce_str>\r\n");
                arrayParams.add("nonce_str=" + nonce_str);

                sbXml.append("  <bill_date>" + Format.Date8Format.format(dateFrom)
                        + "</bill_date>\r\n");
                arrayParams.add("bill_date=" + Format.Date8Format.format(dateFrom));

                String bill_type = getBankConfig().getValueAsString("bill_type");
                if (StringHelper.isNullOrEmpty(bill_type)) {
                    bill_type = "ALL";
                }
                sbXml.append("  <bill_type>" + bill_type + "</bill_type>\r\n");
                arrayParams.add("bill_type=" + bill_type);

                String[] signParams = new String[arrayParams.size()];
                arrayParams.toArray(signParams);
                String sign = signMessage(signParams, actItem.saltKey);
                sbXml.append("  <sign>" + sign + "</sign>\r\n");
                sbXml.append("</xml>");

                // 发送微信并获取返回
                String[] tmpStrRet = sendToBank(sbXml.toString(), "downloadbill");
       /*         if (successCnt == 0) {
                    tmpStrRet[1] = "交易时间,公众账号ID,商户号,子商户号,设备号,微信订单号,商户订单号,用户标识,交易类型,交易状态,付款银行,货币种类,总金额,企业红包金额,微信退款单号,商户退款单号,退款金额,企业红包退款金额,退款类型,退款状态,商品名称,商户数据包,手续费,费率\n" +
                            "`2018-03-10 00:07:48,`wx809ad5a0fecef5e8,`1327950501,`0,`,`4200000001201711093361918537,`10000016486076033522928398,`ooXGUs-hA1kWb8cq6V4z6pYHbzQs,`APP,`SUCCESS,`ICBC_DEBIT,`CNY,`6.00,`3.00,`0,`0,`0.00,`0.00,`,`,`钻石,`炒钻石,`0.06000,`1.00%";
                }
                else if(successCnt == 1)
                {
                    tmpStrRet[1] = "交易时间,公众账号ID,商户号,子商户号,设备号,微信订单号,商户订单号,用户标识,交易类型,交易状态,付款银行,货币种类,总金额,企业红包金额,微信退款单号,商户退款单号,退款金额,企业红包退款金额,退款类型,退款状态,商品名称,商户数据包,手续费,费率\n" +
                            "`2018-03-11 00:07:48,`wx809ad5a0fecef5e8,`1327950501,`0,`,`4200000001201711093361918538,`10000016486076033522928399,`ooXGUs-hA1kWb8cq6V4z6pYHbzQs,`APP,`SUCCESS,`ABC_DEBIT,`CNY,`0.00,`0.00,`0,`0,`500.00,`100.00,`无条件,`SUCCESS,`宝石,`炒宝石,`0.06000,`1.00%";
                }*/
                if (tmpStrRet[0].length() == 0) {
                    if (tmpStrRet[1].indexOf("<xml") >= 0) {// 无对账单
                        StringBuilder tmpSbMsg = new StringBuilder();
                        XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);

                        if (tmpBkReader != null) {
                            String return_code = tmpBkReader.getFirstText("/xml/return_code");
                            String return_msg = tmpBkReader.getFirstText("/xml/return_msg");
                            String error_code = tmpBkReader.getFirstText("/xml/error_code");
                            tmpRespInfo = StringHelper.joinNotEmpty("-", error_code, return_msg);
                            if (!return_code.equals("FAIL") || return_msg.equals("No Bill Exist")) {
                                tmpRespCode = "0";
                            } else {
                                tmpRespCode = "-1";
                            }
                        } else {
                            tmpRespCode = "-1";
                            tmpRespInfo = tmpSbMsg.toString();
                        }
                    } else {
                        tmpRespCode = "0";

                        StringReader strReader = new StringReader(tmpStrRet[1]);
                        BufferedReader tmpReader = new BufferedReader(strReader);

                        int int1 = 65279;
                        String line1 = tmpReader.readLine();
                        int idxHdChar = line1.indexOf(int1);
                        if (idxHdChar >= 0) {
                            line1 = line1.substring(idxHdChar + 1);
                        }
                        String[] columns = line1.split(",");
                        while (true) {
                            String eachline = tmpReader.readLine();
                            if (eachline == null) {
                                break;
                            }
                            String[] values = eachline.split(",");
                            if (columns.length == values.length) {
                                HashMap<String, String> mapKV = SplitHelper.splitAsValueMap(columns, values);
                                RetAtsTransDetail retDetail = new RetAtsTransDetail();

                                if (mapKV.containsKey("公众账号ID")) {
                                    String appId = mapKV.get("公众账号ID").replace("`", "");
                                    if (appId.equals(actItem.appId)) {
                                        retDetail.actNum = appId;
                                        if (mapKV.containsKey("总金额")) {
                                            retDetail.tranAmt = mapKV.get("总金额").replace("`", "");
                                        }
                                        if (mapKV.containsKey("交易时间")) {
                                            retDetail.tranTime = mapKV.get("交易时间").replace("`", "");
                                            retDetail.tranDate = retDetail.tranTime.substring(0, 10);
                                            retDetail.valueDate = retDetail.tranDate;
                                        }
                                        if (mapKV.containsKey("商户订单号")) {
                                            retDetail.askNumber = mapKV.get("商户订单号").replace("`", "");
                                        }
                                        if (mapKV.containsKey("商户订单号")) {
                                            retDetail.payCode = mapKV.get("商户订单号").replace("`", "");
                                        }

                                        if (mapKV.containsKey("商户数据包")) {
                                            retDetail.usage = mapKV.get("商户数据包").replace("`", "");
                                        }
                                        if (mapKV.containsKey("手续费")) {
                                            BigDecimal fee = new BigDecimal(mapKV.get("手续费").replace("`", ""));
                                            retDetail.fee = Format.DecimalAmtFormat.format(fee);
                                        }

                                        if (mapKV.containsKey("商品名称")) {
                                            retDetail.goodsName = mapKV.get("商品名称").replace("`", "");
                                        }

                                        if (mapKV.containsKey("付款银行")) {
                                            retDetail.recAccBank = mapKV.get("付款银行").replace("`", "");
                                        }

                                        //ATSES-23454，现场反馈收支标志反了，通过配置项设置收支标志
                                        if (getBankConfig().getValueAsBool("reverseCDFlag")) {
                                            if (mapKV.containsKey("订单金额")) {
                                                BigDecimal decimal = new BigDecimal(mapKV.get("订单金额").replace("`", ""));
                                                if (decimal.signum() > 0) {
                                                    retDetail.tranAmt = Format.DecimalAmtFormat.format(decimal);
                                                    retDetail.cdFlag = "2";
                                                }
                                            }
                                            if (mapKV.containsKey("退款金额")) {
                                                BigDecimal decimal = new BigDecimal(mapKV.get("退款金额").replace("`", ""));
                                                if (decimal.signum() > 0) {
                                                    retDetail.refundAmt = Format.DecimalAmtFormat.format(decimal);
                                                    retDetail.tranAmt = retDetail.refundAmt;
                                                    retDetail.cdFlag = "1";
                                                }
                                            }
                                        } else {
                                            if (mapKV.containsKey("订单金额")) {
                                                BigDecimal decimal = new BigDecimal(mapKV.get("订单金额").replace("`", ""));
                                                if (decimal.signum() > 0) {
                                                    retDetail.tranAmt = Format.DecimalAmtFormat.format(decimal);
                                                    retDetail.cdFlag = "1";
                                                }
                                            }
                                            if (mapKV.containsKey("退款金额")) {
                                                BigDecimal decimal = new BigDecimal(mapKV.get("退款金额").replace("`", ""));
                                                if (decimal.signum() > 0) {
                                                    retDetail.refundAmt = Format.DecimalAmtFormat.format(decimal);
                                                    retDetail.tranAmt = retDetail.refundAmt;
                                                    retDetail.cdFlag = "2";
                                                }
                                            }
                                        }



                                        if (mapKV.containsKey("设备号")){
                                            retDetail.possCode = mapKV.get("设备号").replace("`", "");
                                        }

                                        if (mapKV.containsKey("代金券或立减优惠金额")) {
                                            BigDecimal decimal = new BigDecimal(mapKV.get("代金券或立减优惠金额").replace("`", ""));
                                            retDetail.benefitAmt = Format.DecimalAmtFormat.format(decimal);
                                        }
                                        if (mapKV.containsKey("企业红包金额")) {
                                            BigDecimal decimal = new BigDecimal(mapKV.get("企业红包金额").replace("`", ""));
                                            retDetail.benefitAmt = Format.DecimalAmtFormat.format(decimal);
                                        }


                                        if (mapKV.containsKey("代金券或立减优惠退款金额")) {
                                            BigDecimal decimal = new BigDecimal(mapKV.get("代金券或立减优惠退款金额").replace("`", ""));
                                            retDetail.refundBenefitAmt = Format.DecimalAmtFormat.format(decimal);
                                        }
                                        if (mapKV.containsKey("企业红包退款金额")) {
                                            BigDecimal decimal = new BigDecimal(mapKV.get("企业红包退款金额").replace("`", ""));
                                            retDetail.refundBenefitAmt = Format.DecimalAmtFormat.format(decimal);
                                        }

                                        if (mapKV.containsKey("手续费")) {
                                            BigDecimal decimal = new BigDecimal(mapKV.get("手续费").replace("`", ""));
                                            retDetail.fee = Format.DecimalAmtFormat.format(decimal);
                                        }

                                        if (mapKV.containsKey("费率")) {
                                            BigDecimal decimal = new BigDecimal(mapKV.get("费率").replace("`", "").replace("%", ""));
                                            retDetail.feeRate = Format.DecimalAmtFormat.format(decimal);
                                        }

                                        retAts.writeRetDetail(retDetail);

                                    }
                                }
                            } else {
                                break;
                            }
                        }
                    }
                } else {
                    tmpRespCode = "-1";
                    tmpRespInfo = tmpStrRet[1];
                }
            } else {
                tmpRespCode = "-1";
                tmpRespInfo = "未找到账号[" + p_req7516.actNum + "]商户配置信息";
            }

            if (tmpRespCode.equals("-1")) {
                failMsg.append(tmpRespInfo).append("|");
            } else {
                successCnt++;
            }

            dateFrom.setTime(dateFrom.getTime() + 3600 * 24 * 1000);
        }

        if (successCnt == 0) {
            retAts = new RetAtsTrans(reqHeader);
            retAts.writeStart();
            retAts.writeRespCode("-1");
            retAts.writeRespInfo(failMsg.toString());
        }

        retAts.writeEnd();
        return retAts;
    }

    public RetAtsTrans d_7516_FundHisTrans(Req7516HisTrans p_req7516) throws Exception {
        RetAtsTrans retAts = new RetAtsTrans(reqHeader);
        retAts.writeStart();

        String tmpRespCode;
        String tmpRespInfo = "";

        Date dateFrom = p_req7516.getDateFrom();
        Date dateTo = p_req7516.getDateTo();


        int successCnt = 0;
        StringBuilder failMsg = new StringBuilder();
        while (dateFrom.compareTo(dateTo) <= 0) {
            try {
                ActSetItem actItem = this.getBankConfig().getActSetItemByAny(p_req7516.actNum, "", "", "wxpay");
                if (actItem != null) {
                    StringBuilder sbXml = new StringBuilder();
                    ArrayList<String> arrayParams = new ArrayList<String>();

                    sbXml.append("<xml>\r\n");
                    String appid = actItem.appId;
                    sbXml.append("  <appid>" + appid + "</appid>\r\n");
                    arrayParams.add("appid=" + appid);

                    String mch_id = actItem.merchantId;
                    sbXml.append("  <mch_id>" + mch_id + "</mch_id>\r\n");
                    arrayParams.add("mch_id=" + mch_id);

                    String nonce_str = get_nonce_str();
                    sbXml.append("  <nonce_str>" + nonce_str + "</nonce_str>\r\n");
                    arrayParams.add("nonce_str=" + nonce_str);

                    sbXml.append("  <sign_type>HMAC-SHA256</sign_type>\r\n");
                    arrayParams.add("sign_type=HMAC-SHA256");

                    sbXml.append("  <bill_date>" + p_req7516.dateFrom + "</bill_date>\r\n");
                    arrayParams.add("bill_date=" + p_req7516.dateFrom);

                    String account_type = getBankConfig().getValueAsString("account_type");
                    if (StringHelper.isNullOrEmpty(account_type)) {
                        account_type = "Basic";
                    }
                    sbXml.append("  <account_type>" + account_type + "</account_type>\r\n");
                    arrayParams.add("account_type=" + account_type);

                    String[] signParams = new String[arrayParams.size()];
                    arrayParams.toArray(signParams);

                    String sign = signMessage(signParams, actItem.saltKey);
                    sbXml.append("  <sign>" + sign + "</sign>\r\n");
                    sbXml.append("</xml>");

                    // 发送微信并获取返回
                    String[] tmpStrRet = sendToBank(sbXml.toString(), "paymentStatement", actItem);
                    if (tmpStrRet[0].length() == 0) {
                        if (tmpStrRet[1].indexOf("<xml") >= 0) {// 无对账单
                            StringBuilder tmpSbMsg = new StringBuilder();
                            XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);

                            if (tmpBkReader != null) {
                                String return_code = tmpBkReader.getFirstText("/xml/return_code");
                                String return_msg = tmpBkReader.getFirstText("/xml/return_msg");
                                String error_code = tmpBkReader.getFirstText("/xml/error_code");
                                tmpRespInfo = StringHelper.joinNotEmpty("-", error_code, return_msg);
                                if (!return_code.equals("FAIL") || return_msg.equals("No Bill Exist")) {
                                    tmpRespCode = "0";
                                } else {
                                    tmpRespCode = "-1";
                                }
                            } else {
                                tmpRespCode = "-1";
                                tmpRespInfo = tmpSbMsg.toString();
                            }
                        } else {
                            tmpRespCode = "0";

                            StringReader strReader = new StringReader(tmpStrRet[1]);
                            BufferedReader tmpReader = new BufferedReader(strReader);

                            int int1 = 65279;
                            String line1 = tmpReader.readLine();
                            int idxHdChar = line1.indexOf(int1);
                            if (idxHdChar >= 0) {
                                line1 = line1.substring(idxHdChar + 1);
                            }
                            String[] columns = line1.split(",");
                            while (true) {
                                String eachline = tmpReader.readLine();
                                if (eachline == null) {
                                    break;
                                }
                                String[] values = eachline.split(",");
                                if (columns.length == values.length) {
                                    HashMap<String, String> mapKV = SplitHelper.splitAsValueMap(columns, values);
                                    RetAtsTransDetail tmpRetDetail = new RetAtsTransDetail();
                                    // 每笔明细记录：记账时间,微信支付业务单号,资金流水单号,业务名称,业务类型,收支类型,收支金额（元）,账户结余（元）,资金变更提交申请人,备注,业务凭证号
                                    if (mapKV.containsKey("收支金额（元）")) {
                                        tmpRetDetail.tranAmt = mapKV.get("收支金额（元）").replace("`", "");
                                    }
                                    if (mapKV.containsKey("记账时间")) {
                                        tmpRetDetail.tranTime = mapKV.get("记账时间").replace("`", "").replace("-", "").replace(":", "").replace(" ", "");
                                    }
                                    if (mapKV.containsKey("资金流水单号")) {
                                        tmpRetDetail.askNumber = mapKV.get("资金流水单号").replace("`", "");
                                    }
                                    if (mapKV.containsKey("微信支付业务单号")) {
                                        tmpRetDetail.seqId = mapKV.get("微信支付业务单号").replace("`", "");
                                    }
                                    if (mapKV.containsKey("账户结余（元）")) {
                                        tmpRetDetail.accBal = mapKV.get("账户结余（元）").replace("`", "");
                                    }
                                    if (mapKV.containsKey("业务类型")) {
                                        tmpRetDetail.busType = mapKV.get("业务类型").replace("`", "");
                                    }
                                    String cdFlag = "22";
                                    if (mapKV.containsKey("收支类型")) {
                                        cdFlag = mapKV.get("收支类型").replace("`", "");
                                        if ("支出".equals(cdFlag)) {
                                            tmpRetDetail.cdFlag = "27";
                                        } else {
                                            tmpRetDetail.cdFlag = cdFlag;
                                        }
                                    }
                                    retAts.writeRetDetail(tmpRetDetail);
                                } else {
                                    break;
                                }
                            }
                        }
                    } else {
                        tmpRespCode = "-1";
                        tmpRespInfo = tmpStrRet[1];
                    }
                } else {
                    tmpRespCode = "-1";
                    tmpRespInfo = "未找到账号:[" + p_req7516.actNum + "]商户配置信息!";
                }
            } catch (Exception ex) {
                ex.printStackTrace();
                tmpRespCode = "-1";
                tmpRespInfo = ex.getMessage();
                WriteBankLogLn(ex);
            }

            if (tmpRespCode.equals("-1")) {
                failMsg.append(tmpRespInfo).append("|");
            } else {
                successCnt++;
            }

            dateFrom.setTime(dateFrom.getTime() + 3600 * 24 * 1000);
        }

        if (successCnt == 0) {
            retAts = new RetAtsTrans(reqHeader);
            retAts.writeStart();
            retAts.writeRespCode("-1");
            retAts.writeRespInfo(failMsg.toString());
        }

        retAts.writeEnd();
        return retAts;
    }

    @Override
    public RetAtsTrans d_7515_TodayTrans(Req7515TodayTrans p_req7515) throws Exception {
        RetAtsTrans trans = new RetAtsTrans(reqHeader);
        trans.writeRespCode("-1");
        trans.writeRespInfo("微信当日对账单需要隔日才能获取");
        return trans;
    }
}
